import tkinter as tk
import tktk
from tkinter import ttk
import serial
# import serial.tools.list_ports
from CfgFrame import PortSetFrame
from PortFrame import PortFrame
from _DataBaseFrame import AtDaTaBaseFrame
from barFrame import barFrame
from VarBind import VarBind

class AtTerminalApp:
    def __init__(self) -> None:
        self.win = tk.Tk()
        self.win.geometry("900x480")
        self.win.title("ATCOM v_0.1 串口调试工具 bili:凿寂")
        self.port = None
        self.varbind = VarBind(self.win)
        self._design()
        self._varbind()
        self._event()
        self._init()
    def _design(self):
        self.row1=tk.PanedWindow(self.win,orient=tk.HORIZONTAL,width=111)
        self.at_recv = tktk.LogFrame(self.row1)
        self.at_cmd_area = tk.Frame(self.row1)
        self.atdataframe=AtDaTaBaseFrame(self.at_cmd_area)
        self.row1.add(self.at_recv)
        self.row1.add(self.at_cmd_area)

        self.row2=barFrame(self.win)

        self.row3=tk.Frame(self.win)
        self.portframee=PortFrame(self.row3)
        self.portframee.pack(side='left')
        self.portsetframee=PortSetFrame(self.row3)
        self.portsetframee.pack(side='left',anchor='n')
        self._layout()
    def _varbind(self):
        self.portframee.m_BindVar(self.varbind)
        self.portsetframee.m_BindVar(self.varbind)
        # self.portsetframee.
    def _init(self):
        self.at_recv_flush()
    def at_send_core(self,msg:str,ishex:bool,istri:bool):
        if self.port!=None:
            try:
                if istri:
                    ...
                    # self.port.write(msg.encode("GBK",errors='ignore'))
                elif ishex:
                    temp=""
                    msg = f"{msg}\r\n"
                    for idx in msg:
                        # print(hex(ord(idx)))
                        temp+="{:0>2}".format(hex(ord(idx)).replace("0x",""))
                    msg=temp.upper()
                    self.varbind.vardict_str["stri_str"].set(msg)
                    # self.port.write(msg.encode("GBK",errors='ignore'))
                else:
                    if self.varbind.vardict_bool["enterreturn_bool"].get():
                        msg = f"{msg}\r\n"
                ss=self.port.write(msg.encode("GBK",errors='ignore'))
                print(ss)
                if self.varbind.vardict_bool["timestap_bool"].get():
                    msg = "\r\n发->{}".format(msg)
                    self.at_recv.m_Gui_LogInsert(msg,True)
            except:
                pass
    def at_send(self):
        if self.varbind.vardict_bool["stri_bool"].get():
            self.at_send_core(self.varbind.vardict_str["stri_str"].get(),True,True)
            # self.at_send_core(self.varbind.vardict_str["stri_str"].get(),False)
        elif self.varbind.vardict_bool["hexsend_bool"].get():
            # msg = self.portsetframee.m_GetStr()
       
            self.at_send_core(self.portsetframee.m_GetStr(),True,False)
        else:
            self.at_send_core(self.portsetframee.m_GetStr(),False,False)
        
    def at_recv_flush(self):
        # print("flush")
        if self.port==None:
            self.portframee.m_SetButtonState(True)
            # self.portframee.e_port.SetStateOption(True)
            self.win.after(200,self.at_recv_flush)
        elif self.port.is_open:
            self.portframee.m_SetButtonState(False)
            # self.portframee.e_port.SetStateOption(False)
            try:
                msg = self.port.read_all()
                if msg!=b'':
                    if self.varbind.vardict_bool["timestap_bool"].get():
                        msg = "\r\n收<-{}".format(msg.decode("GBK",errors='ignore'))
                    else:
                        msg = msg.decode("GBK",errors='ignore')
                    self.at_recv.m_Gui_LogInsert(msg,True)
                    print(f"recv:{len(msg)}")
                    
                    # if len(self.at_recv.scText.get(1.0,'end'))>5000:
                    #     self.at_recv.scText.delete(1.0,2500)
                self.win.after(20,self.at_recv_flush)
            except:
                self.win.after(200,self.at_recv_flush)

    def opencomport(self):
        if self.port==None:
            try:
                self.port=serial.Serial(self.portframee.tmp.get().split(" ",maxsplit=1)[0])
                self.port.baudrate = self.varbind.vardict_int["bound_int"].get()
                self.port.timeout = 20
                self.port.open()
            except Exception as e:
                print(e)
                # showerror("端口打开失败！",f"{e}")
                # print(e)
        else:
            self.port=None
    def _layout(self):
        self.row1.pack(fill=tk.X)
        self.row2.pack(fill=tk.X)
        self.row3.pack(fill=tk.X)
        self.row1.grid_columnconfigure(0,weight=1)

        # self.at_recv.pack()
        # self.aaa.pack()
        ...
        # self.at_recv.grid(column=0,row=0)
    def _event(self):
        self.row2.b_clear_recv.configure(command=self.at_recv.m_Gui_LogClear)
        self.row2.b_clear_send.configure(command=self.portsetframee.m_ClearSend)
        self.portframee.b_openport.configure(command=self.opencomport)
        self.portframee.b_Send.configure(command=self.at_send)
        self.atdataframe.CallBack=self.at_send_core
        self.win.protocol("WM_DELETE_WINDOW", self.on_closing)
        ...
    def on_closing(self):
        # if messagebox.askokcancel("Quit","Do you want to quit?"):
        self.varbind.save()
        self.atdataframe._save_cfg()
        self.win.destroy()



        

    
        
    def run(self):
        self.win.mainloop()

if __name__=="__main__":
    app = AtTerminalApp()
    app.run()